//
// Created by hjie on 23-9-24.
//

#pragma once

#include <cstdint>
#include <cstring>
#include <mutex>
#include <string>
#include <unistd.h>
#include <map>
#include <vector>
#include <memory>
#include <errno.h>
#include <arpa/inet.h>
#include "stun_message.h"

class MessageProcess;
class StunUdpServer;

class StunServerManager
{
public:
    explicit StunServerManager(MessageProcess * message_process, const std::string & public_ip);
    std::shared_ptr<StunUdpServer> CreateUdpServer(const std::string & nonce_data);
    std::shared_ptr<StunUdpServer> FindStunServerByNonceId(const std::string & nonce_id);
    std::shared_ptr<StunUdpServer> FindStunServerByAddress(AttrXorMappedAddress * address);

    void ProcessMessage(StunUdpServer * server, StunMessage & message);
    void CheckAndSwapAllocaterInfo();
    void CheckRelayServerExpire();
    void CheckPort();
    std::shared_ptr<StunUdpServer> FindStunServerByPort(uint16_t server_port);
    uint16_t GetServerPortByNonceId(const std::string & nonce_id);
private:
    MessageProcess * m_message_process;
    std::string m_public_ip;
private:
    std::mutex m_mtx;
    std::map<uint16_t, std::shared_ptr<StunUdpServer>> m_stun_udp_server_map;
    std::map<std::string, uint16_t> m_nonce_port_map;
};
